﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Gunningine
{
    namespace Rendersystems
    {
        namespace OpenGL
        {
            using OpenTK;
            using OpenTK.Graphics;
            using OpenTK.Graphics.OpenGL;
            using Gunningine;

            internal class TextureGL : Texture
            {
                /// <summary>
                /// Constructor.
                /// </summary>
                /// <param name="width"></param>
                /// <param name="height"></param>
                /// <param name="channels"></param>
                /// <param name="data"></param>
                public TextureGL(int width, int height, int channels, IntPtr data)
                    : base(width, height, channels, data)
                {
                    this.Id = GL.GenTexture();

                    Bind();

                    OpenTK.Graphics.OpenGL.PixelFormat pixelFormatGL;
                    OpenTK.Graphics.OpenGL.PixelInternalFormat pixelFormatInt;

                    if (channels == 3)
                    {
                        pixelFormatInt = OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgb;
                        pixelFormatGL = OpenTK.Graphics.OpenGL.PixelFormat.Bgr;
                    }
                    else
                    {
                        pixelFormatInt = OpenTK.Graphics.OpenGL.PixelInternalFormat.Rgba;
                        pixelFormatGL = OpenTK.Graphics.OpenGL.PixelFormat.Bgra;
                    }

                    GL.TexImage2D(TextureTarget.Texture2D, 0, pixelFormatInt, width, height, 0,
                                  pixelFormatGL, PixelType.UnsignedByte, data);

                    // We haven't uploaded mipmaps, so disable mipmapping (otherwise the texture will not appear).
                    // On newer video cards, we can use GL.GenerateMipmaps() or GL.Ext.GenerateMipmaps() to create
                    // mipmaps automatically. In that case, use TextureMinFilter.LinearMipmapLinear to enable them.
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

                    // Unbind texture now we're done with it.
                    Unbind();
                }

                /// <summary>
                /// Destructor.
                /// </summary>
                ~TextureGL()
                {
                    Dispose();
                }

                /// <summary>
                /// Load texture into texture unit.
                /// </summary>
                public override void Bind()
                {
                    GL.BindTexture(TextureTarget.Texture2D, this.Id);
                }

                /// <summary>
                /// Unload texture
                /// </summary>
                public override void Unbind()
                {
                    GL.BindTexture(TextureTarget.Texture2D, 0);
                }

                /// <summary>
                /// Dispose.
                /// </summary>
                protected override void DisposeImpl()
                {
                    //GL.DeleteTexture(this.Id);
                }
            }
        }
    }
}
